<template>
  <section class="todoapp">
    <!-- 除了驼峰, 还可以使用-转换链接 -->
    <TodoHeader :list="list" @addtask="addTaskHandler"></TodoHeader>
    <TodoMain @delTask="delTaskHandler" :list="showList"></TodoMain>
    <TodoFooter
      @clearDone="clearDoneHandler"
      @changeTask="changeTaskHandler"
      :list="showList"
    ></TodoFooter>
  </section>
</template>

<script>
// 1.0 样式引入
import "./styles/base.css";
import "./styles/index.css";
// 父传子流程
// 子组件中定义props 接收数据 并使用
// 父组件绑定属性传递数据

// 子传父流程
// 父组件中给子组件绑定一个自定义事件
// 子组件在恰当的时机触发事件并传递数据

// 目标1 渲染列表
// 1.1 在APP.vue 中声明数据list 并传递给子组件 TodoMain.vue
// 1.2使用v-for 循环渲染 li  动态绑定数据
// 1.3使用 v-model 绑定勾选状态
// 1.4动态 class 根据isDone 来绑定类名

// 目标2 添加数据
// 2.1在 TodoHeader.vue 中双向绑定文本框,同时绑定键盘按下事件(.enter 修饰符)
// 2.2当用户输入内容后按下回车时 将任务名传递给父组件
// 2.3父组件封装成对象后添加到数组中
// 2.4在TodoHeader.vue 中如果用户输入回车添加数据后 清空文本框
// 2.5 进行非空校验

// 目标3 删除数据
// 3.1 在todoMain.vue中给删除按钮绑定点击事件,并传入id
// 3.2 利用子传父技术将 id传递给父组件App.Vue
// 3.3 在父组件中通过 id 找到对应数据的索引,删除数据
// 3.4 数据全部删完后再添加需要处理 id 的bug

// 目标4. 剩余数量统计
// 4.1 在APP.vue中将list 传入todoFooter.vue
// 4.2 在剩余数量处使用插值表达式渲染list.length

// 目标5. 数据切换
// 需求1. 点谁谁亮
// 5.1 定义状态 isAll 取值范围是 all/yes/no
// 5.2 给三个 a 标签绑定动态calss,分别判断是自己的状态时才应用selected类名
// 5.3 给三个 a 标签绑定点击事件,点击时切换isSel 为自己的状态
// 需求2. 数据切换
// 5.4 在todoFooter 中给ul 绑定点击事件(事件委托)
// 5.5 isSel 变化时将数据传递给App.vue
// 5.6 将子组件传递过来的数据存储在data中
// 5.7 定义计算属性 根据data中的isSel来决定返回什么数据(filter 筛选数据)
// 5.8 修饰传递给 todoMain 和 todoFooter 的list 为 showList

// 目标6. 清除已完成
// 6.1 todoFooter.vue 中给清除已完成标签绑定点击事件
// 6.2 子传父技术,触发父组件的事件,无需传递数据
// 6.3 App.vue 中直接操作原数组 list 筛选出来完成的任务数组直接覆盖给list

// 目标7. 数据缓存
// 7.1 在App.vue 中使用watch 深度侦听list
// 7.2 当list 变化时存入 localstorage(JSON.stringify)
// 7.3 页面加载时,默认从 localstorage 中取出数据,注意默认值得处理

// 目标8. 全选功能
// 需求1. 全选影响小选
// 8.1 将list 从App.vue 中传给 todoHeader.vue
// 8.2 定义计算属性 isAll,在set方法中同步 list中所有的数据 isDone属性
// 需求2. 小选影响全选
// 8.3 在get 方法中使用every 同步所有的勾选状态
// 8.4 需要处理无数据的情况
import TodoHeader from "./components/TodoHeader";
import TodoMain from "./components/TodoMain";
import TodoFooter from "./components/ToduFooter";

export default {
  components: {
    TodoHeader,
    TodoMain,
    TodoFooter,
  },
  data() {
    return {
      // 默认从本地取值
      list: JSON.parse(localStorage.getItem("list") || "[]"),
      // 先中转接收类型字符串
      isSel: "all", //显示默认全部
    };
  },
  methods: {
    // 添加任务
    addTaskHandler(taskName) {
      // 当数据删除完毕后需要处理id
      let id =
        this.list.length > 0 ? this.list[this.list.length - 1].id + 1 : 100;
      // push到数组里面
      this.list.push({
        id,
        name: taskName,
        isDone: false,
      });
    },
    // 删除任务
    delTaskHandler(id) {
      let index = this.list.findIndex((item) => item.id === id);
      this.list.splice(index, 1);
    },
    changeTaskHandler(isSel) {
      this.isSel = isSel;
    },
    clearDoneHandler() {
      // 删除已完成
      // 由于 showList 依赖原数组 list 所以直接操作原数组list即可
      // 数据变化 showList 会自动更新
      this.list = this.list.filter((item) => !item.isDone);
    },
  },
  computed: {
    // 根据isSel 的值来决定筛选什么数据返回
    showList() {
      if (this.isSel === "no") {
        return this.list.filter((item) => !item.isDone);
      } else if (this.isSel === "yes") {
        return this.list.filter((item) => item.isDone);
      } else {
        return this.list; //isSel或list 一旦发生变化,showList会重新执行
      }
    },
  },
  // 数据缓存
  watch: {
    list: {
      deep: true,
      handler() {
        // 只要list变化 - 覆盖式保存到localStorage里  存入本地
        localStorage.setItem("list", JSON.stringify(this.list));
      },
    },
  },
};
</script>